<ng-container *ngIf="(this.layerTimelineModel$ | async) as model">
  <div class="studio-layer-timeline mat-elevation-z8"
    *ngIf="(this.themeService.asObservable() | async) as theme"
    [class.dark-to-light-base100]="!theme.isInitialPageLoad && theme.themeType === 'light'"
    [class.light-to-dark-base100]="!theme.isInitialPageLoad && theme.themeType === 'dark'">
    <app-splitter [edge]="'top'"
      (split)="onTopSplitterChanged()"
      [min]="200"
      [persistId]="'layer-timeline'">
    </app-splitter>

    <div class="slt-layers mat-elevation-z2"
      fxLayout="column"
      [class.dark-to-light-base100]="!theme.isInitialPageLoad && theme.themeType === 'light'"
      [class.light-to-dark-base100]="!theme.isInitialPageLoad && theme.themeType === 'dark'">
      <app-splitter [edge]="'right'"
        [min]="200"
        [persistId]="'layer-list'">
      </app-splitter>

      <div class="slt-header mat-elevation-z2"
        fxLayout="row"
        fxLayoutAlign="start center">

        <!-- File menu. -->
        <mat-menu #fileMenu="matMenu">
          <button mat-menu-item
            (click)="this.onNewWorkspaceClick()">
            New
          </button>
          <button mat-menu-item
            (click)="this.onLaunchFilePickerClick($event, 'openFileButton')">
            Open
            <input id="openFileButton"
              type="file"
              accept=".shapeshifter"
              (click)="$event.stopPropagation()"
              (change)="this.onImportedFilesPicked($event, ($event.target || $event.srcElement).files)">
          </button>
          <button mat-menu-item
            (click)="this.onSaveToFileClick()">
            Save
          </button>
          <button mat-menu-item
            (click)="this.onLoadDemoClick()">
            Demo
          </button>
        </mat-menu>
        <button class="slt-layers-menu-group-button"
          (click)="$event.stopPropagation()"
          [matMenuTriggerFor]="fileMenu">
          File
        </button>

        <!-- Import menu. -->
        <mat-menu #importMenu="matMenu">
          <button mat-menu-item
            (click)="this.onLaunchFilePickerClick($event, 'addPathsFromSvgButton')">
            SVG
            <input multiple
              id="addPathsFromSvgButton"
              type="file"
              accept=".svg"
              (click)="$event.stopPropagation()"
              (change)="this.onImportedFilesPicked($event, ($event.target || $event.srcElement).files)">
          </button>
          <button mat-menu-item
            (click)="this.onLaunchFilePickerClick($event, 'addPathsFromXmlButton')">
            Vector Drawable
            <input multiple
              id="addPathsFromXmlButton"
              type="file"
              accept=".xml"
              (click)="$event.stopPropagation()"
              (change)="this.onImportedFilesPicked($event, ($event.target || $event.srcElement).files)">
          </button>
        </mat-menu>
        <button class="slt-layers-menu-group-button"
          (click)="$event.stopPropagation()"
          [ngClass]="{'is-disabled': model.isActionMode}"
          [disabled]="model.isActionMode"
          [matMenuTriggerFor]="importMenu">
          Import
        </button>

        <!-- Export menu. -->
        <mat-menu #exportMenu="matMenu">
          <button mat-menu-item
            (click)="this.onExportSvgClick()">
            SVG
          </button>
          <button mat-menu-item
            (click)="this.onExportVectorDrawableClick()">
            Vector Drawable
          </button>
          <button mat-menu-item
            (click)="this.onExportAnimatedVectorDrawableClick()">
            Animated Vector Drawable
          </button>
          <button mat-menu-item
            (click)="this.onExportSvgSpritesheetClick()">
            SVG spritesheet
          </button>
          <!--<button mat-menu-item
          [disabled]="true"
          (click)="this.onExportCssKeyframesClick()">
          CSS keyframes
        </button>-->
        </mat-menu>
        <button class="slt-layers-menu-group-button"
          (click)="$event.stopPropagation()"
          [ngClass]="{'is-disabled': model.isActionMode}"
          [disabled]="model.isActionMode"
          [matMenuTriggerFor]="exportMenu">
          Export
        </button>

        <div fxFlex></div>

        <!-- Add layer menu. -->
        <mat-menu #addLayerMenu="matMenu">
          <button mat-menu-item
            (click)="this.onAddPathLayerClick()">
            New path
          </button>
          <button mat-menu-item
            (click)="this.onAddClipPathLayerClick()">
            New clip path
          </button>
          <button mat-menu-item
            (click)="this.onAddGroupLayerClick()">
            New group layer
          </button>
        </mat-menu>
        <button mat-icon-button
          (click)="$event.stopPropagation()"
          matTooltip="Add layer"
          matTooltipPosition="below"
          matTooltipShowDelay="500"
          [disabled]="model.isActionMode"
          [matMenuTriggerFor]="addLayerMenu">
          <mat-icon svgIcon="addlayer"></mat-icon>
        </button>
      </div>

      <div appScrollGroup="timeline"
        class="slt-layers-list-scroller"
        fxFlex>
        <!-- Layer list. -->
        <div class="slt-layers-list">
          <!-- Note the *ngFor loop is intentional here even though there is only
             ever one layer in the list. We use it because it allows us to recreate
             the component from scratch when the layer id changes (i.e. when
             the workspace is reset). -->
          <app-layerlisttree fxLayout="column"
            class="slt-layer-container"
            *ngFor="let vectorLayer of [model.vectorLayer]; trackBy: trackLayerFn"
            [layer]="vectorLayer"
            (layerClick)="this.onLayerClick($event.event, $event.layer)"
            (layerToggleExpanded)="this.onLayerToggleExpanded($event.event, $event.layer)"
            (layerToggleVisibility)="this.onLayerToggleVisibility($event.event, $event.layer)"
            (layerMouseDown)="this.onLayerMouseDown($event.event, $event.layer)"
            (addTimelineBlockClick)="this.onAddTimelineBlockClick($event.event, $event.layer, $event.propertyName)"
            (convertToClipPathClick)="this.onConvertToClipPathClick($event.event, $event.layer)"
            (convertToPathClick)="this.onConvertToPathClick($event.event, $event.layer)"
            (flattenGroupClick)="this.onFlattenGroupClick($event.event, $event.layer)">
          </app-layerlisttree>
        </div>
        <div *ngIf="(this.dragIndicatorObservable | async) as dragData"
          class="slt-layers-list-drag-indicator"
          [ngStyle]="{
            'display': dragData.isVisible ? 'block' : 'none',
            'left': dragData.left + 'px',
            'top': dragData.top + 'px'
          }">
        </div>
        <div class="slt-layers-empty"
          *ngIf="model.vectorLayer.children.length === 0 && model.animation.blocks.length === 0">
          To get started, drag + drop an SVG file here
        </div>
      </div>
    </div>

    <!-- Animation timeline. -->
    <div #timeline
      class="slt-timeline"
      (mousewheel)="this.onWheelEvent($event)">
      <div #timelineAnimation
        *ngIf="{ horizZoom: (this.horizZoomObservable | async) } as animationData"
        class="slt-timeline-animation is-active"
        [ngStyle]="{'width': (model.animation.duration * animationData.horizZoom + 40) + 'px'}"
        fxLayout="column">
        <div class="slt-header mat-elevation-z2">
          <div fxLayout="row"
            fxLayoutAlign="start center">
            <div class="slt-timeline-animation-meta"
              [class.is-disabled]="model.isActionMode"
              [class.is-selected]="model.isAnimationSelected"
              (click)="this.onAnimationHeaderTextClick($event)">
              <span class="slt-timeline-animation-name"
                [class.is-disabled]="model.isActionMode">
                {{ model.animation.name }}
              </span>
              <span class="slt-timeline-animation-duration"
                [class.is-disabled]="model.isActionMode">
                {{ model.animation.duration }}ms
              </span>
            </div>
            <button mat-icon-button
              (click)="this.onZoomToFitClick($event)"
              matTooltip="Zoom to fit ({{ this.shortcutService.getZoomToFitText() }})"
              matTooltipPosition="below"
              matTooltipShowDelay="500">
              <mat-icon>zoom_out_map</mat-icon>
            </button>
          </div>
          <canvas appLayerTimelineGrid
            class="slt-timeline-header-grid"
            [class.dark-to-light-base100]="!theme.isInitialPageLoad && theme.themeType === 'light'"
            [class.light-to-dark-base100]="!theme.isInitialPageLoad && theme.themeType === 'dark'"
            [animation]="model.animation"
            [horizZoom]="animationData.horizZoom"
            [isHeader]="true"
            (scrub)="this.onTimelineHeaderScrub($event)">
          </canvas>
        </div>
        <canvas appLayerTimelineGrid
          class="slt-timeline-grid"
          [isHeader]="false"
          [animation]="model.animation"
          [horizZoom]="animationData.horizZoom">
        </canvas>

        <div appScrollGroup="timeline"
          class="slt-timeline-animation-scroller">
          <div class="slt-timeline-animation-rows">
            <!-- Note the *ngFor loop is intentional here even though there is only
               ever one layer in the list. We use it because it allows us to recreate
               the component from scratch when the layer id changes (i.e. when
               the workspace is reset). -->
            <app-timelineanimationrow *ngFor="let vl of [model.vectorLayer]; trackBy: trackLayerFn"
              [layer]="vl"
              (timelineBlockMouseDown)="this.onTimelineBlockMouseDown($event.event, $event.block)"
              (timelineBlockClick)="this.onTimelineBlockClick($event.event, $event.block)"
              (timelineBlockDoubleClick)="this.onTimelineBlockDoubleClick($event.event, $event.block)">
            </app-timelineanimationrow>
          </div>
        </div>
      </div>
    </div>
  </div>
</ng-container>